package com.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

public class FieldReflect {
	/*
	 * 反射机制，所谓反射说白了就是开挂一样的列出来class里面定义的方法(method) 字段(field) 注解 构造等神器等玩意
	 * 通过反射可以更加开放的编写代码，创造一些自己等架构，自己等规范。
	 * 反射可以降低逻辑直接耦合(逻辑全团一起)
	 * 
	 */
	public int b;
	private int a;
	public void fieldReflect(){
		Class clazz = FieldReflect.class;
		/*
		 *  得到类下所有字段
		 *  一下两种获取方式区别
		 *  getDeclaredFields 获得包含所有的方法,因为在访问时 拥有非public修饰字段 一定环境下是无法被访问的。这个方法可以将所有返回
		 *  getFields		  仅包含能够访问到的字段
		 */
		
		Field[] fields_1 = clazz.getDeclaredFields();
		Field[] fields_2 = clazz.getFields();
	}
	/*
	 * 方法反射的使用，当反射一个方法后，我们通常通过调用get set 来获取或修改字段的数据。
	 *  
	 */
	
	public void set(Field field,Object obj,Object value) throws IllegalArgumentException, IllegalAccessException{
		// 设置字段访问权限,如果不设置默认为false 当使用不可被访问到到字段时，会发生权限异常,所以需要设置保证可以修改数据
		field.setAccessible(true);
		field.set(obj, value);
	}
	
	public static Object get(Field field,Object obj) throws IllegalArgumentException, IllegalAccessException{
		// 设置字段访问权限,如果不设置默认为false 当使用不可被访问到到字段时，会发生权限异常,所以需要设置保证可以修改数据
		field.setAccessible(true);
		return field.get(obj);
	}
	
	// TODO 例子 通过反射将对象字段转换为 一层 map key-val
	public Map<String, Object> toMap(Object obj){
		if(obj == null){
			return null;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		Class clazz = obj.getClass();
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			// 是final修饰 的不填充
			if(Modifier.isFinal(field.getModifiers())){
				continue;
			}
			// 是static修饰的 不填充
			if(Modifier.isStatic(field.getModifiers())){
				continue;
			}
			try{
				field.setAccessible(true);
				map.put(field.getName(), field.get(obj));
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		return map;
	}
	// TODO 例子 将map填充对象字段
	public void setObj(Map<String, Object> map,Object obj){
		Class clazz = obj.getClass();
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			// 是final修饰 的不填充
			if(Modifier.isFinal(field.getModifiers())){
				continue;
			}
			// 是static修饰的 不填充
			if(Modifier.isStatic(field.getModifiers())){
				continue;
			}
			try{
				Object value = map.get(field.getName());
				if(value!=null){
					field.setAccessible(true);
					field.set(obj, map.get(value));
				}
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	
}
